﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;

namespace MMTMemory
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        // USE THIS TO DEFINE THE DIMENSION OF THE MEMORY
        private const int rows = 4;
        private const int colums = 6;

        private int pairs = rows * colums / 2;
        private string baseUri = "";
        private List<Image> rectPressed = new List<Image>();
        private IDictionary<string, Image> images = new Dictionary<string, Image>();
        private bool wasCorrect = false;

        public Window1()
        {
            InitializeComponent();
            this.baseUri = Environment.CurrentDirectory;

            this.WindowState = WindowState.Maximized;

            // grid init
            maingrid.ShowGridLines = true;
            for (int a = 0; a < rows; a++)
                maingrid.RowDefinitions.Add(new RowDefinition());
            for (int b = 0; b < colums; b++)
                maingrid.ColumnDefinitions.Add(new ColumnDefinition());

            // import images
            if (!Directory.Exists(baseUri + @"\images"))
            {
                // error
                this.program.Children.Clear();
                TextBlock t = new TextBlock();
                t.Inlines.Add(new Run("Error. Imagefolder not found:"));
                t.Inlines.Add(new LineBreak());
                t.Inlines.Add(new Bold(new Run(baseUri + @"\images")));
                t.HorizontalAlignment = HorizontalAlignment.Center;
                this.program.Children.Add(t);
                return;
            }

            DirectoryInfo di = new DirectoryInfo(baseUri+@"\images");
            FileInfo[] fi = di.GetFiles("pic*.png"); // ALL PNG IMAGES ARE USED. If you need JPG or other, change it to .jpg ...
            Random rand = new Random();
            List<int> fields = new List<int>();
            int x = 0, y = 0, counter = 0;

            if (!File.Exists(baseUri + @"\images\background.png"))
            {
                // error
                this.program.Children.Clear();
                TextBlock t = new TextBlock();
                t.Inlines.Add(new Run("Error. Backgroundimage not found:"));
                t.Inlines.Add(new LineBreak());
                t.Inlines.Add(new Bold(new Run(baseUri + @"\images\background.png")));
                t.HorizontalAlignment = HorizontalAlignment.Center;
                this.program.Children.Add(t);
                return;
            }

            BitmapImage backgroundBmp = new BitmapImage(new Uri(baseUri+@"\images\background.png"));

            foreach (var file in fi)
            {
                counter++;

                if (counter > rows * colums)
                    break;

                BitmapImage bi = new BitmapImage(new Uri(file.FullName));
                Image img = new Image();
                img.Source = bi;
                img.Visibility = Visibility.Hidden;
                img.MouseUp += new MouseButtonEventHandler(img_MouseUp);

                x = rand.Next(colums);
                y = rand.Next(rows);

                while (fields.Contains((x*10)+y))
                {
                    x = rand.Next(colums);
                    y = rand.Next(rows);
                }

                fields.Add((x * 10) + y);
                Grid.SetColumn(img, x);
                Grid.SetRow(img, y);
                maingrid.Children.Add(img);

                Int32Rect srcRect = new Int32Rect(x * backgroundBmp.PixelWidth / colums, y * backgroundBmp.PixelHeight / rows, backgroundBmp.PixelWidth / colums, backgroundBmp.PixelHeight / rows);
                int stride = (srcRect.Width * backgroundBmp.Format.BitsPerPixel + 7) / 8;
                byte[] pp = new byte[srcRect.Height * stride];
                Image bg = new Image();

                try
                {
                    PixelFormat pf = PixelFormats.Bgra32;
                    backgroundBmp.CopyPixels(srcRect, pp, stride, 0);
                    BitmapSource bgSrc = BitmapSource.Create(srcRect.Width, srcRect.Height, 96, 96, pf, null, pp, stride);
                    
                    bg.Source = bgSrc;
                    bg.Stretch = Stretch.Fill;
                    bg.MouseUp += new MouseButtonEventHandler(rect_MouseUp);

                    Grid.SetColumn(bg, x);
                    Grid.SetRow(bg, y);
                    maingrid.Children.Add(bg);
                }
                catch (Exception ex)
                {
                    ;
                }

                this.images[file.Name.Substring(0, file.Name.IndexOf("."))] = img;
                bg.Name = file.Name.Substring(0, file.Name.IndexOf("."));
            }
        }

        void img_MouseUp(object sender, MouseButtonEventArgs e)
        {
            this.mainborder.BorderBrush = new SolidColorBrush(Color.FromRgb(255, 255, 255));

            if (this.rectPressed.Count == 2)
                clearRect();
        }

        private void clearRect()
        {
            if (!this.wasCorrect)
            {
                this.rectPressed[0].Visibility = Visibility.Visible;
                this.rectPressed[1].Visibility = Visibility.Visible;
                this.images[this.rectPressed[0].Name].Visibility = Visibility.Hidden;
                this.images[this.rectPressed[1].Name].Visibility = Visibility.Hidden;
            }
            else
            {
                this.images[this.rectPressed[0].Name].Opacity = 0.3;
                this.images[this.rectPressed[1].Name].Opacity = 0.3;
            }

            this.rectPressed.Clear();
        }

        void rect_MouseUp(object sender, MouseButtonEventArgs e)
        {
            this.mainborder.BorderBrush = new SolidColorBrush(Color.FromRgb(255, 255, 255));

            if (this.rectPressed.Count == 2)
            {
                clearRect();
            }
            else
            {
                ((Image)sender).Visibility = Visibility.Hidden;
                this.rectPressed.Add((Image)sender);
                this.images[((Image)sender).Name].Visibility = Visibility.Visible;

                // check if correct
                if (this.rectPressed.Count == 2)
                {
                    string name1 = this.rectPressed[0].Name.Substring(0, this.rectPressed[0].Name.Length - 1);
                    string name2 = this.rectPressed[1].Name.Substring(0, this.rectPressed[1].Name.Length - 1);
                    if (name1.Equals(name2))
                    {   // correct
                        this.mainborder.BorderBrush = new SolidColorBrush(Color.FromRgb(0, 255, 0));
                        this.wasCorrect = true;

                        this.pairs--;

                        if (this.pairs == 0)
                        {
                            foreach (var child in this.maingrid.Children)
                            {
                                if (((UIElement)child).Visibility == Visibility.Visible)
                                    ((UIElement)child).Opacity = 1.0;
                            }                            
                        }
                    }
                    else
                    {
                        this.mainborder.BorderBrush = new SolidColorBrush(Color.FromRgb(255, 0, 0));
                        this.wasCorrect = false;
                    }
                }
            }
        }

    }
}
